package com.levi.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.levi.common.Constants;
import com.levi.common.CustomException;
import com.levi.common.LeaveEnum;
import com.levi.domain.Leave;
import com.levi.mapper.LeaveMapper;
import com.levi.service.FlowableService;
import com.levi.service.LeaveService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author shentong
 * @date 2021/8/16 12:16
 * @Description TODO
 */
@Service
public class LeaveServiceImpl extends ServiceImpl<LeaveMapper,Leave> implements LeaveService {

    @Autowired
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;

    @Autowired
    private FlowableService flowableService;

    @Override
    public Leave add(Leave leave) {
        baseMapper.insert(leave);
        return leave;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(String id) {
        Leave leave = verify(id);
        if (!leave.getStatus().equals(LeaveEnum.TO_BE_COMMIT.getCode())) {
            throw new CustomException("只能提交待提交的申请");
        }
        //提交申请之后，开启流程
        leave.setStatus(LeaveEnum.TO_BE_REVIEW.getCode());
        //如果没有流程实例id，就开启流程
        Map<String, Object> map = new HashMap<>(1);
        map.put("taskUser","王五");
        if (leave.getProcessId() == null) {
            //开启流程
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(Constants.FLOW_KEY_LEAVE, id, map);
            //设置流程实例id
            leave.setProcessId(processInstance.getId());
        }
        baseMapper.updateById(leave);
        /**
         * 获取当前提交的userTask，并且完成   设置
         * 设置 王五 为请假申请人，实际项目中用当前登录人
         */
        String taskId = flowableService.getTaskIdByUserAndBussinessId("王五", id);
        taskService.complete(taskId,null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void review(String id,Integer result,String remark) {
        Leave leave = verify(id);
        Map<String,Object> map =new HashMap<>();
        map.put("result", result);
        /**
         * 一级审批人是张三，二级审批人是李四
         * 以及审批时候需要设置为张三，二级审批时候需要设置为李四，且需要重启项目
         * 实际项目中设置为当前登录人即可
         */
        String taskId = flowableService.getTaskIdByUserAndBussinessId("李四", id);
        taskService.complete(taskId,map);
        //完成当前任务之后在判断是否还有下一个任务
        if (result.equals(LeaveEnum.REVIEW_PASSED.getCode())) {
            List<Task> taskList = flowableService.getTasksByProcessInstanceId(leave.getProcessId());
            if (CollectionUtils.isEmpty(taskList)) {
                leave.setStatus(LeaveEnum.REVIEW_PASSED.getCode());
                leave.setRemark(remark);
                baseMapper.updateById(leave);
            }
        }else if (result.equals(LeaveEnum.REVIEW_FILED.getCode())){
            leave.setStatus(LeaveEnum.REVIEW_FILED.getCode());
            leave.setRemark(remark);
            baseMapper.updateById(leave);
        }else {
            throw new CustomException("数据不同步");
        }
    }

    /**
     * 验证数据是否存在
     * @param id
     * @return
     */
    private Leave verify(String id) {
        Leave leave = baseMapper.selectById(id);
        if (leave == null) {
            throw new CustomException("数据不存在");
        }
        return leave;
    }
}
